package com.pig4cloud.pig.djjk.service.wd;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pig4cloud.pig.djjk.config.DeviceConfig;
import com.pig4cloud.pig.djjk.constant.MoveDirection;
import com.pig4cloud.pig.djjk.domain.entity.XCCJZP;
import com.pig4cloud.pig.djjk.domain.po.Alert;
import com.pig4cloud.pig.djjk.domain.po.DeviceInfo;
import com.pig4cloud.pig.djjk.domain.po.FaceLibSearchResp;
import com.pig4cloud.pig.djjk.entity.DeviceEntity;
import com.pig4cloud.pig.djjk.entity.TrackRecordEntity;
import com.pig4cloud.pig.djjk.mapper.TrackRecordMapper;
import com.pig4cloud.pig.djjk.mapper.XCCJZPMapper;
import com.pig4cloud.pig.djjk.service.DeviceService;
import com.pig4cloud.pig.djjk.service.TrackAnalysisService;
import com.pig4cloud.pig.djjk.service.immi.FaceApiService;
import com.wd.ais.domain.dto.DetectFaceQualityRequest;
import com.wd.ais.domain.dto.DetectFaceQualityResponse;
import com.wd.ais.service.AisToolsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.awt.*;
import java.io.File;
import java.util.List;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

@Service
public class WdboxService {
	Logger log = Logger.getLogger(WdboxService.class.getName());
	@Autowired
	private FaceApiService faceApiService;
	@Autowired
	XCCJZPMapper xccjzpMapper;

	@Autowired
	TrackAnalysisService trackAnalysisService;

	@Autowired
	TrackRecordMapper trackRecordMapper;
	@Autowired
	DeviceService deviceService;

	@Resource
	WdTrackService wdTrackService;


	@Autowired
	AisToolsService aisToolsService;

	@Value("${wd.server.url}")
	private String serverUrl;


	static short ptzZoomPosDefault = 0;

	public static boolean WRITE_STATE = true;


	@Autowired
	DeviceConfig deviceConfig;


//    public boolean remoteDeviceInfo() {
//        try {
//            String res = HttpUtil.get(serverUrl + "/device/list");
//            JSONObject jsonObject = JSONUtil.parseObj(res);
//            JSONArray data = jsonObject.getJSONArray("data");
//            if (CollUtil.isNotEmpty(data)) {
//                for (int i = 0; i < data.size(); i++) {
//                    JSONObject deviceObj = data.getJSONObject(i);
//                    DeviceInfo deviceInfo = new DeviceInfo();
//                    deviceInfo.setDeviceId(deviceObj.getStr("deviceCode"));
//                    deviceInfo.setDeviceIP(deviceObj.getStr("deviceIp"));
//                    deviceInfo.setDeviceName(deviceObj.getStr("deviceName"));
//                    deviceInfo.setDeviceAccount(deviceObj.getStr("deviceAccount"));
//                    deviceInfo.setDevicePwd(deviceObj.getStr("devicePwd"));
//                    deviceInfo.setBoardRight(deviceObj.getStr("devicePosition").equals("1"));
//                    deviceInfo.setDevicePort(deviceObj.getInt("devicePort"));
//                    deviceInfo.setAutoLadder(deviceObj.getStr("ladderModel").equals("1"));
//                    deviceInfoMap.put(deviceObj.getStr("deviceCode"), deviceInfo);
//                    deviceMap.put(deviceObj.getStr("deviceCode"), "init");
//                }
//                return true;
//            }
//        } catch (Exception e) {
//            return false;
//        }
//        return false;
//    }

	@PostConstruct
	public void init() {
		List<DeviceEntity> deviceEntities = deviceService.list(new LambdaQueryWrapper<DeviceEntity>().isNotNull(DeviceEntity::getDeviceIp)
				.isNotNull(DeviceEntity::getDeviceAccount)
				.isNotNull(DeviceEntity::getDevicePwd)
		);
		for (DeviceEntity deviceEntity : deviceEntities) {
			DeviceInfo deviceInfo = new DeviceInfo();
			deviceInfo.setDeviceId(deviceEntity.getDeviceCode());
			deviceInfo.setDeviceIP(deviceEntity.getDeviceIp());
			deviceInfo.setDeviceName(deviceEntity.getDeviceName());
			deviceInfo.setDeviceAccount(deviceEntity.getDeviceAccount());
			deviceInfo.setDevicePwd(deviceEntity.getDevicePwd());
			deviceInfo.setBoardRight(deviceEntity.getDevicePosition().equals("1"));
			deviceInfo.setDevicePort(Convert.toInt(deviceEntity.getDevicePort()));
			deviceInfo.setAutoLadder(deviceEntity.getLadderModel().equals("1"));
			deviceInfoMap.put(deviceEntity.getDeviceCode(), deviceInfo);
			deviceMap.put(deviceEntity.getDeviceCode(), "init");
		}
//        if (remoteDeviceInfo()) {
//
//        } else {
//            deviceConfig.getDevices().forEach((deviceId, deviceName) -> {
//                List<String> params = StrUtil.split(deviceName, ",");
//                DeviceInfo deviceInfo = new DeviceInfo();
//                deviceInfo.setDevicePort(8000);
//                deviceInfo.setDeviceAccount(params.get(1));
//                deviceInfo.setDevicePwd(params.get(2));
//                deviceInfo.setDeviceName(deviceId);
//                deviceInfo.setDeviceIP(params.get(0));
//                deviceInfo.setAutoLadder(false);
//                if (params.get(3).equals("left")) {
//                    deviceInfo.setBoardRight(false);
//                } else {
//                    deviceInfo.setBoardRight(true);
//                }
//                deviceInfoMap.put(deviceId, deviceInfo);
//            });
//        }
//        HikSdkUtil.initSDK(deviceInfoMap);
	}

	public void eventHandler(String eventJson) {
		if (StrUtil.isEmpty(eventJson)) {
			log.info("box event null");
			return;
		}
		if (!JSONUtil.isTypeJSON(eventJson)) {
			log.warning("box event string is not json");
			return;
		}
		JSONObject eventObj = JSONUtil.parseObj(eventJson);
		JSONObject alg = eventObj.getJSONObject("alg");

		String deviceId = eventObj.getJSONObject("source").getStr("id");
		if (deviceInfoMap.containsKey(deviceId)) {
			DeviceInfo deviceInfo = deviceInfoMap.get(deviceId);
			if (deviceInfo.getAutoLadder()) {
				log.info("自动梯控触发");
			} else {
				log.info("自动梯控关闭");
				return;
			}
		}

		log.info("识别类型:" + alg.getStr("name"));
		if (StrUtil.equals("match_face", alg.getStr("type"))) {
			faceHandler(eventObj);
		} else {
			//如果是舷梯
			if (StrUtil.equals("spiral_staircase", alg.getStr("name"))) {
//                ladderHandler(eventObj);
				wdTrackService.ladderPositionHandler(eventObj);
			}
			//如何是人员徘徊
			else if (StrUtil.equals("custom_loitering", alg.getStr("name"))) {
				// moveHandler(eventObj);
				wdTrackService.traceHandler(eventObj);
			} else {
				return;
			}
		}

	}

	//    static float offsetXCoefficient = 240/1280f;
	static float offsetXCoefficient = 240 / 1280f;
	static float offsetYCoefficient = 220 / 720f;
//    static float offsetYCoefficient = 480/720f;

	TimedCache<String, String> deviceStatusCache = new TimedCache<>(60 * 5 * 1000);
	static Map<String, String> deviceMap = new HashMap<>();
	public static Map<String, DeviceInfo> deviceInfoMap = new HashMap<>();

	//    TimedCache<String, String> ladderCache = new TimedCache<>(10000);

	/**
	 * 检测不到梯子自动回归预置点
	 * 暂时不用
	 */
//    @Scheduled(initialDelay = 3000, fixedRate = 10000)
//    public void ladderCheckTask() {
//        for (String deviceId : deviceMap.keySet()) {
//            if (!deviceStatusCache.containsKey(deviceId) && !StrUtil.equals(deviceMap.get(deviceId), "preset")) {
//                HikSdkUtil.gotoPreset(deviceId);
//                deviceMap.put(deviceId, "preset");
//                ThreadUtil.sleep(5000);
//                if (ptzZoomPosDefault == 0) {
//                    HCNetSDK.NET_DVR_PTZPOS ptzPos = HikSdkUtil.getPTZPos(deviceId);
//                    ptzZoomPosDefault = ptzPos.wZoomPos;
//                    log.info("预置点：" + ptzZoomPosDefault);
//                }
//            }
//        }
//    }

	/**
	 * 处理失步问题
	 *
	 * @param deviceId
	 */
//    public static void disposeLoseStep(String deviceId) {
//        ThreadUtil.execAsync(() -> {
//            HCNetSDK.NET_DVR_PTZPOS ptzPos = HikSdkUtil.getPTZPos(deviceId);
//            ptzPos.wTiltPos = 1800;
//            HikSdkUtil.setPTZPos(deviceId, ptzPos);
//            ThreadUtil.sleep(20000);
//            HikSdkUtil.gotoPreset(deviceId);
//        });
//    }

	private TimedCache<String, JSONArray> latestPositionCache = CacheUtil.newTimedCache(5 * 60000);
	private TimedCache<String, Integer> ladderTimes = CacheUtil.newTimedCache(5 * 60000);

//    private void ladderHandler(JSONObject eventObj) {
//        log.info("box ladder found");
//        JSONArray rectangles = eventObj.getJSONObject("reserved_data").getJSONObject("bbox").getJSONArray("rectangles");
//        if (CollUtil.isNotEmpty(rectangles)) {
//            JSONArray xyxy = rectangles.getJSONObject(0).getJSONArray("xyxy");
//
//            if (CollUtil.isNotEmpty(xyxy)) {
////                String deviceId = "device1";
//                String deviceId = eventObj.getJSONObject("source").getStr("id");
//
//                if (deviceInfoMap.containsKey(deviceId)) {
//                    DeviceInfo deviceInfo = deviceInfoMap.get(deviceId);
//                    if (deviceInfo.getAutoLadder()) {
//                        log.info("自动梯控触发");
//                    } else {
//                        log.info("自动梯控关闭");
//                        return;
//                    }
//                }
////                if (!deviceConfig.getDevices().containsKey(deviceId)) {
////                    log.info(StrUtil.format("wd box deviceId {} not found,see config file application.yml", deviceId));
////                    return;
////                }
//
////                if(ladderCache.containsKey(deviceId)){
////                }else{
////                    ladderCache.put(deviceId,"1");
////                    return;
////                }
//
//                HCNetSDK.NET_DVR_PTZPOS ptzPos = HikSdkUtil.getPTZPos(deviceId);
//                short wZoomPos = ptzPos.wZoomPos;
//
////                if(!deviceStatusCache.containsKey(deviceId)){
////                    String imageBase64 = eventObj.getStr("image");
////                    BufferedImage image = ImgUtil.toImage(Base64.decode(imageBase64));
////                    int width = image.getWidth();
////                    int height = image.getHeight();
//////                log.info(ptzPos.wPanPos+","+ ptzPos.wTiltPos+","+ ptzPos.wZoomPos);
////                    log.info(xyxy.toString()+","+width+","+height);
////                    executePTZZoomIn(xyxy, deviceId);
////                }
////                deviceMap.put(deviceId,"working");
////                deviceStatusCache.put(deviceId,"working",100000);
//                int x1 = xyxy.getInt(0);
//                int y1 = xyxy.getInt(1);
//                int x2 = xyxy.getInt(2);
//                int y2 = xyxy.getInt(3);
//                int width = x2 - x1;
//                int height = y2 - y1;
//                if (height / 1280f > 0.8) {
//                    log.info("工作中1");
//                    return;
//                }
//
//                log.info("zoom:" + wZoomPos + "," + ptzZoomPosDefault);
//                if (!latestPositionCache.containsKey(deviceId)) {
//                    latestPositionCache.put(deviceId, xyxy);
//                    ladderTimes.put(deviceId, 1);
//                    log.info("第一次识别");
//                    return;
//                } else {
//                    JSONArray firstPosition = latestPositionCache.get(deviceId);
//                    if (Math.abs(firstPosition.getInt(3) - xyxy.getInt(3)) < 20) {
//                        Integer times = ladderTimes.get(deviceId);
//                        if (times == null) times = 0;
//                        times++;
//                        ladderTimes.put(deviceId, times);
//                        if (times == 5) {
//                            changeFocus(xyxy, deviceId);
//                        } else if (times < 5) {
//                            log.info("任务确认中" + times);
//                            return;
//                        }
//                    } else {
//                        log.info("工作中2");
//                        return;
//                    }
//                    latestPositionCache.put(deviceId, xyxy);
//                }
//
////                if(Math.abs(wZoomPos-ptzZoomPosDefault)>1){
////                    log.info("工作狀態不处理");
////                }else{
////                    doWorking(xyxy, deviceId);
////                }
//            }
//        }
//
//    }

//    private void changeFocus(JSONArray xyxy, String deviceId) {
//        executePTZZoomIn(xyxy, deviceId);
//        deviceStatusCache.put(deviceId, "working");
//        deviceMap.put(deviceId, "working");
//        ladderTimes.put(deviceId, 0);
//    }


//    private void executePTZZoomIn(JSONArray xyxy, String deviceId) {
//        HCNetSDK.NET_DVR_POINT_FRAME net_dvr_point_frame = new HCNetSDK.NET_DVR_POINT_FRAME();
//        DeviceInfo deviceInfo = deviceInfoMap.get(deviceId);
//        int x1 = xyxy.getInt(0);
//        int y1 = xyxy.getInt(1);
//        int x2 = xyxy.getInt(2);
//        int y2 = xyxy.getInt(3);
//        int width = x2 - x1;
//        int height = y2 - y1;
//        int x1To = 0, y1To = 0, x2To = 0, y2To = 0;
//        float confX = 0.5f;
//        float confY = 0f;
//        if (width > height) {
//            if (deviceInfo.getBoardRight()) {//船在右边
//                x1To = (int) (x1 - width * confX);
//                x2To = (int) (x1To + height);
//            } else {
//                x1To = (int) (x1 + width * confX);
//                x2To = (int) (x1To + height);
//            }
//            y1To = y1;
//            y2To = y2;
//        } else {
//            if (deviceInfo.getBoardRight()) {//船在右边
//                x1To = (int) (x1 - width * confX);
//                x2To = (int) (x2 - width * confX);
//            } else {
//                x1To = (int) (x1 + width * confX);
//                x2To = (int) (x2 + width * confX);
//            }
////            y1To = (int) (y1 * 1f);
//            y1To = (int) (y2 - width);
//            if (y1To < y1) y1To = y1;
//            y2To = (int) (y2 * 1f) + 30;
//            log.info(x1 + "," + y1 + "," + x2 + "," + y2);
//            log.info(x1To + "," + y1To + "," + x2To + "," + y2To);
//        }
//
//        net_dvr_point_frame.xTop = (int) (x1To * offsetXCoefficient);
//        net_dvr_point_frame.yTop = (int) (y1To * offsetYCoefficient);
//        if (net_dvr_point_frame.yTop < 0) net_dvr_point_frame.yTop = 0;
//        net_dvr_point_frame.xBottom = (int) (x2To * offsetXCoefficient);
//        net_dvr_point_frame.yBottom = (int) (y2To * offsetYCoefficient);
//        if (net_dvr_point_frame.yBottom < 0) net_dvr_point_frame.yBottom = 0;
//        log.info("定位攝像頭坐標：" + net_dvr_point_frame.xTop + "," + net_dvr_point_frame.yTop + "," + net_dvr_point_frame.xBottom + "," + net_dvr_point_frame.yBottom);
//        HikSdkUtil.setPTZZoomIn(deviceId, net_dvr_point_frame);
//        //                    String imageBase64 = eventObj.getStr("image");
////                    BufferedImage image = ImgUtil.toImage(Base64.decode(imageBase64));
////                    int width = image.getWidth();
////                    int height = image.getHeight();
////                    int x1 = xyxy.getInt(0);
////                    int y1 = xyxy.getInt(1);
////                    int x2 = xyxy.getInt(2);
////                    int y2 = xyxy.getInt(3);
////                    int offsetX = (int) ((x1+x2-width)/2*offsetXCoefficient);
////                    int offsetY = (int) ((y1+y2-height)/2*offsetYCoefficient);
////
////                    ptzPos.wPanPos = (short) (ptzPos.wPanPos+offsetX);
////                    ptzPos.wTiltPos = (short) (ptzPos.wTiltPos+offsetY);
////                    HikSdkUtil.setPTZPos(deviceId,ptzPos);
//    }


	//弃用
	private void faceHandler(JSONObject eventObj) {
		Image cut = null;
		log.info("box face found");
		String fileName = System.currentTimeMillis() + ".png";
		String imageBase64 = eventObj.getStr("image");
		FileUtil.writeBytes(Base64.decode(imageBase64), FileUtil.file("box_images/" + fileName));
		JSONArray rectangles = eventObj.getJSONObject("reserved_data").getJSONObject("bbox").getJSONArray("rectangles");
		if (CollUtil.isNotEmpty(rectangles)) {
			JSONArray xyxy = rectangles.getJSONObject(0).getJSONArray("xyxy");
			if (CollUtil.isNotEmpty(xyxy)) {
				cut = ImgUtil.cut(ImgUtil.toImage(imageBase64), new Rectangle(xyxy.getInt(0), xyxy.getInt(1), xyxy.getInt(2) - xyxy.getInt(0), xyxy.getInt(3) - xyxy.getInt(1)));
				ImgUtil.write(cut, FileUtil.file("box_images_cut/" + fileName));
			}
		}

		if (cut != null) {
			String deviceCode = "09057001311310266075";
			byte[] imageByte = ImgUtil.toBytes(cut, ImgUtil.IMAGE_TYPE_PNG);
			if (imageByte == null) {
				System.out.println("人脸库搜索失败，下载图片失败");
				return;
			}
			String rybh = "";
			String scoreStr = "0";
			String base64 = Base64.encode(imageByte);
			FaceLibSearchResp faceLibSearchResp = faceApiService.faceLibSearch(base64);
			if (faceLibSearchResp == null) {
				System.out.println("人脸库搜索失败，人脸识别失败1");

			}
			rybh = faceLibSearchResp.getRybh();
			if (StrUtil.isEmpty(rybh)) {
				log.info("人脸库搜索失败，人脸识别失败2");
				scoreStr = "0";
			} else {

				Float score = faceLibSearchResp.getScore();
				scoreStr = Convert.toStr(score);
			}

			XCCJZP xccjzp = new XCCJZP();
			xccjzp.setRYBH(rybh);
			xccjzp.setXSD(scoreStr);
			xccjzp.setSBBH(deviceCode);
			xccjzp.setCJSJ(DateUtil.format(new Date(), "yyyyMMddHHmmss"));
			xccjzp.setZPZP(imageByte);
			xccjzpMapper.insert(xccjzp);
			xccjzpMapper.callDJJK();
		}
	}
}
